package algorithm.hash;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Security;

import javax.xml.bind.DatatypeConverter;

//hash函数的特点：1）离散性 2）均匀性
//（利用这种均匀性可以对大文件里的数据进行hash、取模（%n）后可以实现n个小文件中数的种类的均匀分配，n=数据量/内存大小，确保每个小文件里的数据量内存能够放得下）
//布隆过滤器（已知的数据大小n,失误率p,内存空间大小m,hash函数的个数k）(n,p -> m)  (m,n -> k) (m,n,k -> p)
//哈希一致性(哈希值环结构组织 + 虚拟节点技术)

/*
*  资源限制技巧
* 1)布隆过滤器用于集合的建立与查询，并可以节省大量空间
* 2)一致性哈希解决数据服务器的负载管理问题
* 3)利用并查集结构做岛问题的并行计算
* 4)哈希函数可以把数据按照种类均匀分流
* 5)位图（用bit位记录状态）解决某一范围上数字的出现情况，并可以节省大量空间
* 6)利用分段统计思想、并进一步节省大量空间（给你几KB的空间就可以将范围分成很多分（例如可以用3KB的空间做整型数组，遍历大文件的时候，内存中数组每个位置记录其表示的范围的特定数据），如果有限变量的话可以用二分）
* 7)利用堆（给大文件排序时，通过给定的内存就知道能构建包含多少（n）记录（值和频次）的大根堆，大根堆的构建只保存前n个最小记录，内存满时就输出到有序文件中，循环）、外排序来做多个处理单元的结果合并
* */
public class Hash {

	private MessageDigest hash;

	public Hash(String algorithm) {
		try {
			hash = MessageDigest.getInstance(algorithm);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
	}

	public String hashCode(String input) {
		return DatatypeConverter.printHexBinary(hash.digest(input.getBytes())).toUpperCase();
	}

	public static void main(String[] args) {
		System.out.println("支持的算法 : ");
		for (String str : Security.getAlgorithms("MessageDigest")) {
			System.out.println(str);
		}
		System.out.println("=======");

		String algorithm = "MD5";
		Hash hash = new Hash(algorithm);

		String input1 = "zuochengyunzuochengyun1";
		String input2 = "zuochengyunzuochengyun2";
		String input3 = "zuochengyunzuochengyun3";
		String input4 = "zuochengyunzuochengyun4";
		String input5 = "zuochengyunzuochengyun5";
		System.out.println(hash.hashCode(input1));
		System.out.println(hash.hashCode(input2));
		System.out.println(hash.hashCode(input3));
		System.out.println(hash.hashCode(input4));
		System.out.println(hash.hashCode(input5));

	}

}
